/* ------------------------------------------Marlin Toolkit---------------------------------------------*
Authors : Daniel Randle, Alex Bourne
Date Created : Feb 20 2013

File:
	debug.cpp

Description:
	This file contains the definition for the Debug class functions along with any
	helper functions associated with the class
*------------------------------------------------------------------------------------------------------*/

// Includes
#include <debug.h>
#include <global.h>
#include <debugwindow.h>
#include <sstream>
using namespace ToolkitGui;


/*----------------------*
 | class Debug BEGINS   |
 *----------------------*/


/* Constructor 1
Description:
	This ctor assigns the display and the logfile associated with the debugging.

Parameters:
	dDisplay : the pointer to a DebugDisplay where the debug will output to
	logFileName : the name of the log file - by default is "debug.txt"
*/
Debug::Debug(DebugWindow * dDisplay, const QString & logFileName):
	display(dDisplay),
	log("",logFileName, QString()),
	autoCls(false),
	mode(LogAndDisplay)
{
	log.writeDate();
}


/* Constructor 2
Description:
	This ctor assigns the logfile associated with the debugging.
	The mode is set to log only because no display is given - you can't enable display mode unless there 
	is a valid display

Parameters:
	logFileName : the name of the log file - by default is "debug.txt"
*/
Debug::Debug(const QString & logFileName):
	display(NULL),
	log("",logFileName, QString()),
	autoCls(false),
	mode(LogAndDisplay)
{
	log.writeDate();
}

Debug::~Debug()
{
}


/*-------------------------------------PUBLIC GET FUNCTIONS--------------------------------------------*/


/* getLogFileName
Description:
	Returns the underlying log file name

Parameters:
	NONE

Return:
	the log file name
*/
const QString & Debug::getLogFileName() const
{

	return log.getFileName();
}


/* getLogDirectory
Description:
	Returns the directory of the log file
	If the directory is the current directory will return QString()

Parameters:
	NONE

Return:
	log file directory
*/
const QString & Debug::getLogDirectory() const
{

	return log.getDirectory();
}


/* getLogWriteMode
Description:
	Gets the current log file write mode

Parameters:
	NONE

Return:
	returns write mode - either APPEND or OVERWRITE
*/
Debug::LogWriteMode Debug::getLogWriteMode() const
{

	return log.getWriteMode();
}


/* isLogTimeStamp
Description:
	Returns whether the current LogFile object has time stamping enabled

Parameters:
	NONE

Return:
	whether timestamping is enabled or not
*/
bool Debug::isLogTimeStamp() const
{

	return log.isTimeStampEnabled();
}


/* getDebugWindow
Description:
	gets the current view window the debug output is being sent to

Parameters:
	NONE

Return:
	pointer to the display - if there is none returns a NULL pointer
*/
DebugWindow * Debug::getDebugWindow() const
{

	return display;
}


/* getOutputMode
Description:
	Gets the current output mode

Parameters:
	NONE

Return:
	returns an OutMode - tells about if the debug is being sent to log and/or display
*/
Debug::OutMode Debug::getOutputMode() const
{

	return mode;
}


/* isAutCls
Description:
	returns whether auto clearing of the screen is enabled - by default it is not

Parameters:
	NONE

Return:
	true or false
*/
bool Debug::isAutCls() const
{

	return autoCls;
}


/*---------------------------------------PUBLIC SET FUNCTIONS------------------------------------------*/


/* setLogFileName
Description:
	sets log file name

Parameters:
	fileName : log file name (as on disk) 

Return:
	None
*/
void Debug::setLogFileName(const QString & fileName)
{

	log.setFileName(fileName);
}


/* setLogDirectory
Description:
	sets the directory of the log file - default is set to current directory
	QString() (invalid qstring) is used to show that the directory is the current directory

Parameters:
	directory : qstring that contains directory (QString() by default)

Return:
	None
*/
void Debug::setLogDirectory(const QString & directory)
{

	log.setDirectory(directory);
}


/* setLogWriteMode
Description:
	Sets the log file write mode - by default it is Append

Parameters:
	mode : the new mode to set

Return:
	None
*/
void Debug::setLogWriteMode(LogWriteMode mode)
{

	log.setWriteMode(mode);
}


/* setLogTimeStamp
Description:
	set whether timestamping is enabled - if enabled there will be a timestamp before each entry in the 
	log file only
	(display not timestamped)

Parameters:
	enabled - bool value saying whether to enable or not

Return:
	None
*/
void Debug::setLogTimeStamp(bool enabled)
{

	log.setTimeStampEnabled(enabled);
}


/* setDebugWindow
Description:
	Sets the display the debug should write to - the debug display handles the actual displaying of text 
	on the screen

Parameters:
	dDisplay : a DebugDisplay type that handles printing to a Qt widget

Return:
	bool
*/
void Debug::setDebugWindow( DebugWindow * dDisplay )
{
	display = dDisplay;
}


/* setOutputMode
Description:
	set the mode of debugging - basically whether it uses the display, log file, or both.
	If the display is a NULL pointer the mode is locked to log file mode only

Parameters:
	m : OutMode stating which of the three modes the debug object should use

Return:
	bool - whether the output mode was successfully changed (if display is NULL pointer will return 
	false)
*/
bool Debug::setOutputMode(OutMode m)
{

	if (display == NULL)
	{
		mode = Log;
		return false;
	}
	mode = m;
	return true;
}


/* setAutCls
Description:
	Set whether the debug display screen clears every time new text is given or not
	By default this value is false
	If the display is a NULL pointer then auto clearing does nothing (makes sense)

Parameters:
	enabled : whether to enable feature or not

Return:
	None
*/
void Debug::setAutCls(bool enabled)
{
	autoCls = enabled;
}


/*-------------------------------------------- PUBLIC INTERFACE ---------------------------------------*/


/* print
Description:
	prints text to screen, log file, or both depending on the mode variable. Also will auto clear the 
	screen if autoCls is
	set to true. If failed to print for any reason will return false (no log file, no display, anything)

Parameters:
	text : QString containg text to be printed

Return:
	bool saying whether function was successful or not
*/
bool Debug::print(const QString & text)
{
	switch (mode)
	{
	case (LogAndDisplay):
		if (display == NULL)   // If display is NULL set mode to log only and return indicating failure
		{
			mode = Log;
			log.write(text + "LogAndDisplayModeError : NO DISPLAY"); // Should never happen in 
																	 // theory but just in case
			return false;                                            // I'll find out quickly
		}
		display->writeToScreen(text);
		if (log.write(text))
			return true;
		display->writeToScreen("Writing to logfile failed");
		return false;
	case (Display):
		if (display == NULL)
		{
			mode = Log;
			log.write(text + "DisplayModeError : NO DISPLAY"); // Should never happen in theory 
															   // but just in case
			return false;                                      // I'll find out quickly
		}
		display->writeToScreen(text);
		return true;
	case (Log):
		if (log.write(text))
			return true;
		return false;
	default:
		return false;
	}
}

/* print
Description:
	prints text to screen, log file, or both depending on the mode variable. Also will auto clear the 
	screen if autoCls is
	set to true. If failed to print for any reason will return false (no log file, no display, anything)

	Overloaded function to help with printing numbers to the debug

Parameters:
	message : message to appear before the number
	num : the number that will be displayed

Return:
	bool saying whether function was successful or not
*/
bool Debug::print(const QString & message, float num)
{
	std::stringstream s;
	s << message.toStdString() << num;
	return print(s.str().c_str());
}


/* cls
Description:
	clears the screen - that simple - If display is NULL then does nothing.

Parameters:
	NONE

Return:
	None
*/
void Debug::cls()
{
	if (display != NULL)
		display->clearScreen();
}


/*----------------------*
 |  class Debug ENDS    |
 *----------------------*/